iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
自我挑戰組

JavaScript 30天挑戰 自學筆記系列 第 23

JS30 自學筆記 Day23_Speech Synthesis

  • 分享至 

  • xImage
  •  

今日任務: 語音合成 (Speech synthesis),將文字轉成語音,
可以選擇播放的語言、控制講話速度和音頻高低

Web Speech API

Web Speech API 提供了兩個不同的功能領域:

  • 語音識別(speech recognition): 通過麥克風接收語音,將語音轉為文字的介面
  • 語音合成(speech synthesis): 將文字合成為語音,並從音頻設備播放的介面。

瀏覽器支援:
對 Web Speech API 語音識別的支援目前只有於桌面版和 Android 版 Chrome

D20的時候我們介紹過語音辨識,今天要來介紹語音合成。

SpeechSynthesisUtterance物件

建立物件

new SpeechSynthesisUtterance():創一個新的SpeechSynthesisUtterance物件來使用,
說話的語言、講話速度和音頻高低、內容都放進這個裡面。

const msg = new SpeechSynthesisUtterance();
let voices = [];
const voicesDropdown = document.querySelector('[name="voice"]');
const options = document.querySelectorAll('[type="range"], [name="text"]');
const speakBtn = document.querySelector('#speak');
const stopBtn = document.querySelector('#stop');

屬性

  • lang:語音的語言。
  • pitch:語音的音高。
  • rate:語音的說話的速度。
  • text:要合成語音的文字。
  • voice:語音的聲音。

將輸入框文字放入SpeechRecognition

msg.text = document.querySelector('[name="text"]').value;
console.log(msg);

SpeechSynthesis

監聽事件

SpeechSynthesis: voiceschanged event: 當SpeechSynthesis物件裡的SpeechSynthesisVoice清單被改變時觸發。

方法

SpeechSynthesis.speak():加一段語音到列隊,前面的說完後就播放此語音。
SpeechSynthesis.cancel():清空語音,如果當前正在講話,講話將立即停止。
SpeechSynthesisVoice: 語音物件。
SpeechSynthesis.getVoices(): 會回傳一個使用者設備上所有可用的SpeechSynthesisVoice清單陣列。

*注意*:
getVoices()需搭配監聽voiceschanged事件,否則會回傳空陣列。

SpeechSynthesisVoice清單與頁面異步加載,所以當SpeechSynthesisVoice被加載的時候voiceschanged事件會被觸發一次,之後會因為getVoices()觸發。
stackoverflow:Getting the list of voices in speechSynthesis

取得所有可用的語音

speechSynthesis.addEventListener('voiceschanged', populateVoices);

function populateVoices() {
    voices= this.getVoices();
    console.log(voices);
}

把這些voices放到input選擇選項裡面

function populateVoices() {
    voices = this.getVoices();
    console.log(voices);
    voicesDropdown.innerHTML = voices
        .map((voice) => 
            `<option value="${voice.name}">${voice.name}(${voice.lang})</option>`)
        .join('');
}

console.log(msg)會看到voice,還是null

設定聲音

聲音有載入但還沒設定
當選項選擇後觸發,在voices中尋找符合使用者選擇的選項的值(this.value)

voicesDropdown.addEventListener('change', setVoice);

function setVoice() {
    msg.voice = voices.find(voice=>voice.name===this.value)
}

選擇選項,並在console裡面輸入speechSynthesis.speak(msg),就會發出聲音

重新選擇語言時,直接播放新語音

function setVoice() {
    msg.voice = voices.find((voice) => voice.name === this.value);
    toggle();
}

function toggle() {
    speechSynthesis.cancel();
    speechSynthesis.speak(msg);
}

有時候可能不想要直接播放新語音,可以傳一個參數來決定要不要直接播放新語音

function toggle(playOver = true) {
    speechSynthesis.cancel();
    if(playOver){
        speechSynthesis.speak(msg);
    }
}

設定講話速度和音頻高低、內容

options.forEach((option) => option.addEventListener('change', setOptions));
function setOptions(){
    console.log(this);
    msg[this.name] = this.value;
    toggle();
}

設定播放和暫停按鈕

不能這樣寫

這樣寫又太冗長

有兩種方法:
1.使用bind()

speakBtn.addEventListener('click', toggle);
stopBtn.addEventListener('click', toggle.bind(null,false));

2.箭頭函式

speakBtn.addEventListener('click', toggle);
stopBtn.addEventListener('click', () => toggle(false));

篩選語言

作者示範篩選語言為英文,這邊篩選中文:

function populateVoices() {
    voices = this.getVoices();
    voicesDropdown.innerHTML = voices
        .filter((voice) =>voice.lang.includes('zh'))
        .map((voice) => `<option value="${voice.name}">${voice.name}(${voice.lang})</option>`)
        .join('');
}

今日學習到的:

  • new SpeechSynthesisUtterance():創一個新的SpeechSynthesisUtterance物件來使用,
    說話的語言、講話速度和音頻高低、內容都放進這個裡面。
  • SpeechSynthesisUtterance物件屬性
    • lang:語音的語言。
    • pitch:語音的音高。
    • rate:語音的說話的速度。
    • text:要合成語音的文字。
    • voice:語音的聲音。
  • SpeechSynthesis
    • 監聽事件
      • SpeechSynthesis: voiceschanged event: 當SpeechSynthesis物件裡的SpeechSynthesisVoice清單被改變時觸發。
    • 方法
      • SpeechSynthesis.speak():加一段語音到列隊,前面的說完後就播放此語音。
      • SpeechSynthesis.cancel():清空語音,如果當前正在講話,講話將立即停止。
      • SpeechSynthesisVoice: 語音物件。
      • SpeechSynthesis.getVoices(): 會回傳一個使用者設備上所有可用的SpeechSynthesisVoice清單陣列。
      • *注意:*:getVoices()需搭配監聽voiceschanged事件,否則會回傳空陣列。

效果連結:連結

參考連結:
MDN: SpeechSynthesisUtterance
MDN: SpeechSynthesis


上一篇
JS30 自學筆記 Day22_Follow Along Links
下一篇
JS30 自學筆記 Day24_Sticky Nav
系列文
JavaScript 30天挑戰 自學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言